import fs from 'fs';
import path from 'path';
import xlsx from 'xlsx';
import chalk from 'chalk';
import ora from 'ora';

const spinner = ora();

function transformLanguage(rootDirectory, languageConfigData) {
  // 获取/tools/lang目录下所有的文件
  const langDir = path.join(rootDirectory, '/tools/lang/');

  const xlsxFiles = languageConfigData.input
    .filter((file) => file.fileName.endsWith('.xlsx'))
    .map((file) => file.fileName);

  // 解析输出配置
  const result = languageConfigData.output.map((config) => {
    const { key, value } = config;
    // 路径组合，输出的文件路径
    const filePath = path
      .join(rootDirectory, '/src/generated/lang/', `${key}.ts`)
      .replace(/\\/g, '/');

    ensureDirectoryExists(path.dirname(filePath));
    return { key, value, path: filePath, object: {} };
  });

  // 存储已处理的 key
  const processedKeys = new Set();

  xlsxFiles.forEach((fileName) => {
    const filePath = path.join(langDir, fileName);

    doesFileExist(filePath, fileName);

    const workbook = xlsx.read(fs.readFileSync(filePath), { type: 'array' });

    const fileIndex = languageConfigData.input.findIndex(
      (item) => item.fileName === fileName
    );

    // 异常处理函数
    if (fileIndex === -1) {
      handleError(chalk.red.bold(`文件 ${fileName} 没有在配置中定义`));
    }

    const sheetNames = languageConfigData.input[fileIndex].sheetNames;
    sheetNames.forEach((sheetName) => {
      const jsonData = xlsx.utils.sheet_to_json(workbook.Sheets[sheetName]);

      jsonData.forEach((json) => {
        if (processedKeys.has(json['key'])) {
          handleError(
            chalk.red.bold(
              `文件 ${fileName} 的工作表 ${sheetName} 存在重复的 key: ${json['key']}`
            )
          );
        }
        processedKeys.add(json['key']);
        // console.log('processedKeys', processedKeys);
        // 正则匹配 %index$@ 替换为 param{index}
        result.forEach((item) => {
          let newValue = json[item.value] + '';

          newValue = newValue.replace(
            /%(\d+)\$@/g,
            (match, index) => `{param${index}}`
          );

          item.object[json['key']] = newValue;
        });
      });
    });
  });

  // 生成 TypeScript 文件
  result.forEach((item) => {
    console.log('item.object', item.object);
    const fileContent = `export default {\n${toSingleQuotedValues(
      item.object
    )}\n}\n`;
    fs.writeFileSync(item.path, fileContent, 'utf-8');
    spinner.succeed(chalk.green(`文件已保存: ${item.path}`));
  });

  // 生成枚举文件 langEnum.ts

  const enumFileContent = `enum LangEnum {\n${result
    .map((item) => `  '${item.key}' = '${item.key}',`)
    .join('\n')}\n}\nexport default LangEnum;`;
  const enumFilePath = path
    .join(rootDirectory, '/src/generated/lang/lang-enum.ts')
    .replace(/\\/g, '/');
  fs.writeFileSync(enumFilePath, enumFileContent, 'utf-8');
  spinner.succeed(chalk.green(`枚举文件已保存: ${enumFilePath}`));
}

/**
 * 异常处理
 * @param errorMessage
 */
function handleError(errorMessage) {
  spinner.fail(chalk.red.bold(errorMessage));
  process.exit(1);
}

/**
 * 辅助函数，目录下的文件是否存在
 * @param filePath 路径
 * @param file 文件名称
 */
function doesFileExist(filePath, fileName) {
  if (!fs.existsSync(filePath)) {
    handleError(chalk.red.bold(`文件 ${fileName} 不存在！`));
  }
}

/**
 * 辅助函数，将对象的值包裹在单引号中
 * @param obj
 * @returns
 */
function toSingleQuotedValues(obj) {
  console.log(
    '%c [  ]-131',
    'font-size:13px; background:pink; color:#bf2c9f;',
    obj
  );
  const entries = Object.entries(obj).map(([key, value]) => {
    const quotedValue = value?.includes("'") ? `${value}` : `'${value}'`;
    return `  ${key}: ${quotedValue}`;
  });
  return entries.join(',\n');
}

/**
 * 辅助函数，确保输出目录存在，不存在则创建
 * @param directoryPath 路径
 */
function ensureDirectoryExists(directoryPath) {
  try {
    fs.mkdirSync(directoryPath, { recursive: true });
  } catch (error) {
    handleError(chalk.red.bold(`创建目录失败: ${directoryPath}: ${error}`));
  }
}

export default function xlsxTransformLanguage() {
  spinner.start();
  spinner.text = 'language脚本生成中...';
  const rootDirectory = process.cwd();
  const configFilePath = path.join(
    rootDirectory,
    '/tools/lang/lang-config.json'
  );

  console.log(
    '%c [  ]-158',
    'font-size:13px; background:pink; color:#bf2c9f;',
    process.cwd()
  );

  // 读取语言配置文件
  const languageConfig = JSON.parse(fs.readFileSync(configFilePath, 'utf-8'));

  transformLanguage(rootDirectory, languageConfig);
}
xlsxTransformLanguage();

/**
 * 1. 配置文件设计 json 文件，input: fileName-sheetName/  output: key
 *
 *
 */
